<?php

namespace app\services;

use plugin\admin\app\model\Goods;
use plugin\admin\app\model\GoodsSKU;
use plugin\admin\app\model\ShoppingCart;

class ShoppingCartService
{
    /**
     *
     * @param $data
     * @param $isOrder 下单场景添加
     * @return \Illuminate\Database\Eloquent\HigherOrderBuilderProxy|int|mixed
     * @throws \Exception
     */
    public static function add($data, $isOrder = 0)
    {
        $goodsInfo = Goods::where('id', $data['goods_id'])->first();

        $isMulti = $goodsInfo['type'] == Goods::TYPE_MULTI_SPEC; //是否多规格

        if (!$isMulti && empty($data['goods_id'])) {
            throw new \Exception('goods_id 参数不能为空');
        }

        $count = $data['count'] ?? 1;
        $type = $isMulti ? Goods::TYPE_MULTI_SPEC : Goods::TYPE_SINGLE_SPEC;
        $id = $isMulti ? $data['sku_id'] : $data['goods_id'];

        if (!GoodsService::isValid($id, $count, $type, $res)) {
            throw new \Exception($res);
        }

        if (!$isOrder && !GoodsService::checkCanAddToCart($id, $type, $res)) {  //如果是下单场景添加，跳过是否能加购物车检查
            throw new \Exception($res);
        }

        $insertData = [
            'user_id' => get_user_id(),
            'count' => $count,
        ];

        if ($isMulti) {
            $sku = GoodsSKU::where('id', $id)->first();

            $insertData['goods_id'] = $sku['goods_id'];
            $insertData['sku_id'] = $id;

            $cartItem = ShoppingCart::where('user_id', get_user_id())->where('goods_id', $sku['goods_id'])->where('sku_id', $id)->where('is_order' , $isOrder)->first();
        } else {
            $insertData['goods_id'] = $id;

            $cartItem = ShoppingCart::where('user_id', get_user_id())->where('goods_id', $id)->where('is_order', $isOrder)->first();
        }

        if ($isOrder) {
            $insertData['is_order'] = 1;
        }

        if ($cartItem) {
            if ($isOrder) {
                $cartItem->count = $data['count'];
            } else {
                $cartItem->count += $data['count'];
            }
            $cartItem->save();

            return $cartItem->id;
        } else {
            return ShoppingCart::insertGetId($insertData);
        }
    }

    public static function incr($data)
    {
        return self::setCount($data, 'incr');
    }

    public static function setCount($data, $changeType = null)
    {
        $cartItemInfo = ShoppingCart::where('user_id', get_user_id())->where('id', $data['id'])->first();

        if (!$cartItemInfo) {
            throw new \Exception('不存在的购物车商品');
        }

        $isMulti = !empty($cartItemInfo['sku_id']);
        $type = $isMulti ? Goods::TYPE_MULTI_SPEC : Goods::TYPE_SINGLE_SPEC;
        $count = $data['count'] ?? $cartItemInfo['count'];
        $id = $isMulti ? $cartItemInfo['sku_id'] : $cartItemInfo['goods_id'];

        if (!is_null($changeType)) {
            if ($changeType == 'incr') {
                $count++;
            } else {
                $count = $count <= 1 ? $count : --$count;
            }
        }

        if (GoodsService::hasStock($id, $count, $type, $stock)) {
            $cartItemInfo->count = $count;
            $cartItemInfo->save();

            return true;
        }

        return [false, $stock];

    }

    public static function reduce($data)
    {
        return self::setCount($data, 'reduce');
    }

    public static function delete($data)
    {
        ShoppingCart::where('user_id', get_user_id())->whereIn('id', $data['ids'])->delete();
    }

    public static function list($ids = [], $isOrder = null)
    {
        $query = ShoppingCart::where('user_id', get_user_id());
        if (count($ids) > 0) {
            $query->whereIn('id', $ids);
        }

        if (!is_null($isOrder)) {
            $query->where('is_order', $isOrder);
        }

        $cartInfo = $query->get()->toArray();

        $goodsIds = array_column($cartInfo, 'goods_id');
        $skuIds = array_column($cartInfo, 'sku_id');

        $goodsList = Goods::select(['id', 'name', 'thumb', 'is_up', 'stock', 'price', 'market_price', 'free_shipping', 'shipping_fee', 'type', 'is_gift', 'is_normal', 'register_integral', 'recharge_integral', 'freeze_integral_rate'])->whereIn('id', $goodsIds)->get()->toArray();
        $goodsList = array_combine(
            array_column($goodsList, 'id'),
            array_values($goodsList)
        );

        $skuList = GoodsSKU::select(['id', 'sku', 'stock', 'price'])->whereIn('id', $skuIds)->get()->toArray();
        $skuList = array_combine(
            array_column($skuList, 'id'),
            array_values($skuList)
        );

        $data = [];
        $totalCount = 0;
        $totalPrice = 0;
        $totalMarketPrice = 0;
        $totalShippingFee = 0;
        $totalPreferentialPrice = 0;
        $totalRechargeIntegral = 0;
        $totalRegisterIntegral = 0;

        foreach ($cartInfo as $key=>$value) {

            $isMulti = !empty($value['sku_id']);

            $type = $isMulti ? Goods::TYPE_MULTI_SPEC : Goods::TYPE_SINGLE_SPEC;
            $id = $isMulti ? $value['sku_id'] : $value['goods_id'];

            $goodsInfo = $goodsList[$value['goods_id']];
            $goodsInfo['thumb'] = full_url($goodsInfo['thumb']);
            $goodsInfo['activity'] = GoodsActivityService::getGoodsJoinActivity($goodsInfo);

            $sku = $skuList[$value['sku_id']] ?? null;

            if ($sku) {
                $sku['sku'] = json_decode($sku['sku'], true);
            }

            $goodsInfo['sku'] = $sku;

            GoodsService::setActivityPrice($goodsInfo, $value);

            $value['goods_info'] = $goodsInfo;

            $value['goods_info']['price'] = !empty($value['goods_info']['sku']) ? $value['goods_info']['sku']['price'] : $value['goods_info']['price'];

            // 购物车的商品是否有效
            if (!GoodsService::isValid($id, $value['count'], $type, $res)) {
                $value['message'] = $res;
                $data['invalid'][] = $value;
            } else {
                $data['valid'][] = $value;

                $totalCount += $value['count'];

                $price = $goodsInfo['sku'] ? $goodsInfo['sku']['price'] : $goodsInfo['price'];
                $totalPrice = bcadd($totalPrice, bcmul($value['count'], $price, 2), 2); //统计价格

                $marketPrice = $goodsInfo['sku'] ? ($goodsInfo['sku']['market_price'] ?? $goodsInfo['market_price']) : $goodsInfo['market_price'];
                $totalMarketPrice = bcadd($totalMarketPrice, bcmul($value['count'], $marketPrice, 2), 2); //统计价格

                $shippingFee = $goodsInfo['free_shipping'] ? 0 : $goodsInfo['shipping_fee'];
                $totalShippingFee = bcadd($totalShippingFee, $shippingFee, 2);

                $preferentialPrice = $goodsInfo['sku'] ? ($goodsInfo['sku']['preferential_price'] ?? 0) : ($goodsInfo['preferential_price'] ?? 0);
                $totalPreferentialPrice = bcadd($totalPreferentialPrice, $preferentialPrice, 2);

                $totalRechargeIntegral = bcadd($totalRechargeIntegral, $goodsInfo['recharge_integral'] ?? 0, 2);
                $totalRegisterIntegral = bcadd($totalRegisterIntegral, $goodsInfo['register_integral'] ?? 0, 2);
            }

        }

        return ['totalCount' => $totalCount, 'totalPrice' => $totalPrice, 'list' => $data, 'totalShippingFee' => $totalShippingFee, 'totalMarketPrice' => $totalMarketPrice, 'totalPreferentialPrice' => $totalPreferentialPrice, 'totalRechargeIntegral' => $totalRechargeIntegral, 'totalRegisterIntegral' => $totalRegisterIntegral, 'totalIntegral' => bcadd($totalRechargeIntegral, $totalRegisterIntegral, 2)];
    }

    public static function isGift($cartItemIds)
    {
        $cartItems = ShoppingCartService::list($cartItemIds, 1);

        if (empty($cartItems['list']['valid'])) {
            return 0;
        }

        $goodsIds = array_column($cartItems['list']['valid'], 'goods_id');
        return GoodsService::isGift($goodsIds[0]);
    }

    public static function isNormal($cartItemIds)
    {
        $cartItems = ShoppingCartService::list($cartItemIds, 1);

        if (empty($cartItems['list']['valid'])) {
            return 0;
        }

        $goodsIds = array_column($cartItems['list']['valid'], 'goods_id');
        return GoodsService::isNormal($goodsIds[0]);
    }

    public static function isIntegral($cartItemIds)
    {
        $cartItems = ShoppingCartService::list($cartItemIds, 1);

        if (empty($cartItems['list']['valid'])) {
            return 0;
        }

        $goodsIds = array_column($cartItems['list']['valid'], 'goods_id');
        return !GoodsService::isGift($goodsIds[0]) && !GoodsService::isNormal($goodsIds[0]);
    }
}